package com.ts.api.module.api.service.impl;

import com.gitee.apanlh.util.base.ChooseEq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.date.DateUtils;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.BizEnum;
import com.ts.api.common.constant.productflow.ProductApplyFlowSrcTypeEnum;
import com.ts.api.common.constant.productflow.ProductApplyFlowStatusEnum;
import com.ts.api.common.constant.protocol.UserProtocolEnum;
import com.ts.api.common.context.ApiContext;
import com.ts.api.common.context.ChannelRequestContext;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.common.redis.ApiMatchRedisKey;
import com.ts.api.common.util.H5DomainUrlUtils;
import com.ts.api.exp.BizException;
import com.ts.api.exp.RollBackException;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.plan.http.ApiPlanHttpHandler;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMd5DataExchange;
import com.ts.api.module.api.convert.receive.entity.ApiReceiveNotice;
import com.ts.api.module.api.convert.receive.http.ApiReceiveNoticeHttpHandler;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.bo.ApiKeyAmountBO;
import com.ts.api.module.api.entity.bo.H5CallbackExistBO;
import com.ts.api.module.api.entity.bo.H5CallbackOrgInfoBO;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.api.service.ApiH5CallBackService;
import com.ts.api.module.api.service.ApiKeyAmountService;
import com.ts.api.module.api.service.ApiUserRegister;
import com.ts.api.module.channel.entity.po.ChannelUserFormFieldPO;
import com.ts.api.module.channel.entity.po.ChannelUserRegisterPO;
import com.ts.api.module.channel.entity.qo.ChannelUserQO;
import com.ts.api.module.channel.service.ChannelFormService;
import com.ts.api.module.channel.service.ChannelUserService;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.common.service.SmsService;
import com.ts.api.module.product.entity.bo.ProductAmountBO;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.entity.qo.ProductApplyFlowQO;
import com.ts.api.module.product.service.ProductAmountService;
import com.ts.api.module.product.service.ProductApplyFlowService;
import com.ts.api.module.product.service.ProductPlanService;
import com.ts.api.module.product.service.ProductPlanTypeService;
import com.ts.api.module.product.service.ProductService;
import com.ts.api.module.protocol.entity.po.ProductProtocolPO;
import com.ts.api.module.protocol.entity.po.UserProtocolPO;
import com.ts.api.module.protocol.entity.qo.ProductProtocolQO;
import com.ts.api.module.protocol.service.ProductProtocolService;
import com.ts.api.module.protocol.service.UserProtocolService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
public class ApiH5CallBackServiceImpl implements ApiH5CallBackService {

    @Autowired
    private ProductApplyFlowService productApplyFlowService;
    @Autowired
    private ChannelUserService channelUserService;
    @Autowired
    private ProductPlanService productPlanService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductAmountService productAmountService;
    @Autowired
    private ApiKeyAmountService apiKeyAmountService;
    @Autowired
    private ChannelFormService channelFormService;
    @Autowired
    private ApiPlanHttpHandler apiPlanHttpHandler;
    @Autowired
    private ApiReceiveNoticeHttpHandler apiReceiveNoticeHttpHandler;
    @Autowired
    private SmsService smsService;
    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private UserProtocolService userProtocolService;
    @Autowired
    private ProductProtocolService productProtocolService;
    @Autowired
    private ProductPlanTypeService productPlanTypeService;
    @Autowired
    private ApiUserRegister apiUserRegister;

    @Override
    public H5CallbackOrgInfoBO getOrgInfo(H5CallbackExistBO apiCallbackExistOrgBO) {
        String applyId = apiCallbackExistOrgBO.getApplyId();
        String clientId = apiCallbackExistOrgBO.getClientId();

        //  获取流程信息
        ProductApplyFlowQO h5ApiCallBack = ProductApplyFlowQO.createH5Callback(applyId, clientId);
        ProductApplyFlowPO productApplyFlowPO = productApplyFlowService.get(h5ApiCallBack);
        Assert.isNotNullThrows(productApplyFlowPO, new BizException(BizEnum.API_CALL_FLOW_EMPTY));

        //  置换机构计划信息
        Long loanProductPlanId = productApplyFlowPO.getLoanProductPlanId();
        ProductPlanPO productPlanPO = productPlanService.get(loanProductPlanId);

        //  插入流程记录表
        if (!apiCallbackExistOrgBO.hasCallUserInto()) {
            ProductApplyFlowPO insertProductApplyFlowPO = new ProductApplyFlowPO();
            insertProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
            insertProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
            insertProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
            insertProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
            insertProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
            insertProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
            insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.CALLBACK_USER_INTO.getType());
            insertProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
            insertProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
            insertProductApplyFlowPO.setFinalIp(ChannelRequestContext.get().getIp());
            //  TODO 增加根据IP获取城市地址
            productApplyFlowService.insert(insertProductApplyFlowPO, false);
        }

        //  业务实体
        H5CallbackOrgInfoBO apiCallBackOrgBO = new H5CallbackOrgInfoBO();
        apiCallBackOrgBO.setName(productPlanPO.getDisplayName());
        apiCallBackOrgBO.setLogoPath(productPlanPO.getLogoPath());

        String applyStatus = ChooseEq.create().when(apiCallbackExistOrgBO.hasCallUserAccept(), true, "1").end("0");
        apiCallBackOrgBO.setApplyStatus(applyStatus);
        return apiCallBackOrgBO;
    }

    @Override
    public void pullApply(ApiKeyPO apiKeyPO, ProductApplyFlowPO productApplyFlowPO) throws RollBackException {
        //  修改日志请求id-一致id
        ApiContext.REQ_ID.remove();
        ApiContext.REQ_ID.set(ClassConvertUtils.toStr(productApplyFlowPO.getReqId()));

        //  获取主体信息
        ProductPO productPO = productService.get(productApplyFlowPO.getLoanProductId());
        //  获取主体计划信息
        ProductPlanPO productPlanPO = productPlanService.get(productApplyFlowPO.getLoanProductPlanId());

        //  记录进件流程日志
        ProductApplyFlowPO insertProductApplyFlowPO = new ProductApplyFlowPO();
        insertProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        insertProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        insertProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        insertProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        insertProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        insertProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.APPLY_ERROR.getType());
        insertProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        insertProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        insertProductApplyFlowPO.setBizStatus("0");
        insertProductApplyFlowPO.setAreaName(productApplyFlowPO.getAreaName());
        insertProductApplyFlowPO.setAreaCode(productApplyFlowPO.getAreaCode());

        //  验证计划时间
        boolean hasLimitTime = apiBizRequiredService.hasLimitTime(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(hasLimitTime, new BizException(BizEnum.API_CALL_ACCEPT_PLAN_TIME_ERROR));

        //  验证机构余额是否足够本次扣款
        boolean requiredProductAmount = apiBizRequiredService.requiredProductAmount(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(requiredProductAmount, new BizException(BizEnum.API_CALL_ACCEPT_AMOUNT_MAX));

        //  推送/拉取进件信息回调-请求对象
        ApiReceiveNotice applyNoticeMessage = new ApiReceiveNotice();
        applyNoticeMessage.setApiClientId(productApplyFlowPO.getApiClientId());
        applyNoticeMessage.setProductId(productPO.getId());
        applyNoticeMessage.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        applyNoticeMessage.setReqId(productApplyFlowPO.getReqId().toString());

        //  拉取进件流程数据
        ProductApplyFlowPO pullNoticeProductApplyFlowPO = new ProductApplyFlowPO();
        pullNoticeProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        pullNoticeProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        pullNoticeProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        pullNoticeProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        pullNoticeProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        pullNoticeProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        pullNoticeProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.CHANNEL_PULL_APPLY_NOTICE.getType());
        pullNoticeProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        pullNoticeProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        pullNoticeProductApplyFlowPO.setBizStatus("0");
        pullNoticeProductApplyFlowPO.setAreaName(productApplyFlowPO.getAreaName());
        pullNoticeProductApplyFlowPO.setAreaCode(productApplyFlowPO.getAreaCode());

        //  将上游通知进件结果保存redis中，上游进件时则根据此标识进件给下游(applyV2接口)
        String applyNoticeFlowKey = ApiMatchRedisKey.getApplyNoticeFlowKey(productApplyFlowPO.getApiClientId(), productApplyFlowPO.getLoanProductPlanId(), productApplyFlowPO.getPhoneMd5());
        ApiMatchRedisKey.API_CHANNEL_APPLY_NOTICE_FLOW.setForMinutes(applyNoticeFlowKey, productApplyFlowPO.getLoanProductPlanId(), 10L);

        //  如果上游渠道设置中的-拉取进件回调不为空则需要向上游发送进件取件回调
        ApiHttpMessage apiPullNoticeHttpMessage = apiReceiveNoticeHttpHandler.sendPullApplyNotice(apiKeyPO, applyNoticeMessage);
        pullNoticeProductApplyFlowPO.setReqData(String.valueOf(apiPullNoticeHttpMessage.getRequestBody()));
        pullNoticeProductApplyFlowPO.setRespData(apiPullNoticeHttpMessage.getResponseBody());
        pullNoticeProductApplyFlowPO.setRespCode(String.valueOf(apiPullNoticeHttpMessage.getRespCode()));
        pullNoticeProductApplyFlowPO.setFinalIp(ChannelRequestContext.get().getIp());

        //  记录上游拉取进件回调流程日志
        boolean hasPullNoticeHttpRespSuc = apiBizRequiredService.hasNoticeHttpRespSuc(pullNoticeProductApplyFlowPO, apiPullNoticeHttpMessage, ProductApplyFlowStatusEnum.CHANNEL_PULL_APPLY_NOTICE);
        if (!hasPullNoticeHttpRespSuc) {
            ApiMatchRedisKey.API_CHANNEL_APPLY_NOTICE_FLOW.delKey(applyNoticeFlowKey);
            throw new BizException(BizEnum.API_CALL_ACCEPT_PULL_APPLY_NOTICE_ERROR);
        }

        //  插入拉取上游申请回调流程日志
        pullNoticeProductApplyFlowPO.setBizStatus("1");
        productApplyFlowService.insert(pullNoticeProductApplyFlowPO, false);
    }

    @Override
    public void apply(ApiKeyPO apiKeyPO, ProductApplyFlowPO productApplyFlowPO) {
        //  修改日志请求id-一致id
        ApiContext.REQ_ID.remove();
        ApiContext.REQ_ID.set(ClassConvertUtils.toStr(productApplyFlowPO.getReqId()));

        String phoneMd5 = productApplyFlowPO.getPhoneMd5();

        //  获取主体信息
        ProductPO productPO = productService.get(productApplyFlowPO.getLoanProductId());
        //  获取主体计划信息
        ProductPlanPO productPlanPO = productPlanService.get(productApplyFlowPO.getLoanProductPlanId());

        //  记录进件流程日志
        ProductApplyFlowPO insertProductApplyFlowPO = new ProductApplyFlowPO();
        insertProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        insertProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        insertProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        insertProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        insertProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        insertProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.APPLY_ERROR.getType());
        insertProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        insertProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        insertProductApplyFlowPO.setBizStatus("0");
        insertProductApplyFlowPO.setAreaName(productApplyFlowPO.getAreaName());
        insertProductApplyFlowPO.setAreaCode(productApplyFlowPO.getAreaCode());

        //  查询用户信息
        ChannelUserQO userQO = new ChannelUserQO();
        userQO.setPhoneMd5(phoneMd5);
        ChannelUserRegisterPO userRegisterPO = channelUserService.get(userQO);
        Long userId = userRegisterPO.getId();

        //  验证计划时间
        boolean hasLimitTime = apiBizRequiredService.hasLimitTime(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(hasLimitTime, new BizException(BizEnum.API_CALL_ACCEPT_PLAN_TIME_ERROR));

        //  验证机构余额是否足够本次扣款
        boolean requiredProductAmount = apiBizRequiredService.requiredProductAmount(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(requiredProductAmount, new BizException(BizEnum.API_CALL_ACCEPT_AMOUNT_MAX));

        //  进件资质校验
        List<ChannelUserFormFieldPO> listUserField = channelFormService.listUserFormField(userId);
        Map<String, String> userFormMap = MapUtils.newHashMap(newMap -> IteratorUtils.array(listUserField, t -> newMap.put(t.getMappingName(), t.getMappingValue())));
        boolean requiredApplyForm = apiBizRequiredService.requiredApplyForm(insertProductApplyFlowPO, productPlanPO, userFormMap);
        Assert.isTrueThrows(requiredApplyForm, new BizException(BizEnum.API_CALL_ACCEPT_APPLY_FIELD_ERROR));

        //  验证空号检测
        boolean requiredPhoneStatus = apiBizRequiredService.requiredPhoneStatus(insertProductApplyFlowPO, productPlanPO, userRegisterPO.getPhone());
        Assert.isTrueThrows(requiredPhoneStatus, new BizException(BizEnum.API_CALL_ACCEPT_APPLY_PHONE_STATUS_ERROR));

        //  是否本地机构
        if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
            insertProductApplyFlowPO.setCallUrl("本地甲方CRM");
        }

        //  设置API请求对象
        ApiUserRequest apiUserRequest = ApiUserRequest.convert(userRegisterPO, listUserField);
        apiUserRequest.setProductId(productApplyFlowPO.getId());
        apiUserRequest.setProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        apiUserRequest.setApiClientId(productApplyFlowPO.getApiClientId());
        apiUserRequest.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        apiUserRequest.setReqId(productApplyFlowPO.getReqId().toString());
        apiUserRequest.setCity(productApplyFlowPO.getAreaName());
        //  设置城市
        DistrictPO districtPO = DistrictCache.getByName(productApplyFlowPO.getAreaName());
        apiUserRequest.setProvinceName(districtPO.getProvinceName());
        apiUserRequest.setProvinceCode(districtPO.getProvinceCode());

        //  判断是否api机构
        boolean hasPlatform = productPlanTypeService.hasPlatformPlan(productPlanPO);
        boolean hasApiOrgPlan = productPlanTypeService.hasApiOrgPlan(productPO, productPlanPO);

        if (hasPlatform || hasApiOrgPlan) {
            ApiHttpMessage httpMessage = apiPlanHttpHandler.sendApply(apiUserRequest, productPO, productPlanPO);
            insertProductApplyFlowPO.setCallUrl(productPO.getApiApplyUrl());
            insertProductApplyFlowPO.setReqData(String.valueOf(httpMessage.getRequestBody()));
            insertProductApplyFlowPO.setRespData(httpMessage.getResponseBody());
            insertProductApplyFlowPO.setRespCode(String.valueOf(httpMessage.getRespCode()));
            if (ChannelRequestContext.get() != null) {
                insertProductApplyFlowPO.setFinalIp(ChannelRequestContext.get().getIp());
            }

            //  是否返回HTTP异常
            boolean hasHttpExp = apiBizRequiredService.hasHttpExp(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (hasHttpExp) {
                throw new BizException(BizEnum.API_CALL_ACCEPT_ERROR);
            }
            //  是否进件返回失败
            boolean hasHttpRespBizSuc = apiBizRequiredService.hasHttpRespBizSuc(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (!hasHttpRespBizSuc) {
                throw new BizException(BizEnum.API_CALL_ACCEPT_ORG_ERROR);
            }

            //  记录下游用户协议
            if (hasPlatform) {
                ProductProtocolQO productProtocolQO = new ProductProtocolQO();
                productProtocolQO.setProductId(productApplyFlowPO.getLoanProductId());
                productProtocolQO.setHasNeedText(true);
                List<ProductProtocolPO> listProductProtocol = productProtocolService.list(productProtocolQO);

                //  添加下游协议
                IteratorUtils.array(listProductProtocol, productProtocolPO -> {
                    String productTemplate = productProtocolPO.getText();

                    //  查询平台模板
                    UserProtocolPO userProtocolPO = new UserProtocolPO();
                    userProtocolPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
                    userProtocolPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
                    userProtocolPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
                    userProtocolPO.setLoanProductProtocolId(productProtocolPO.getId());
                    userProtocolPO.setLoanUserId(userRegisterPO.getId());
                    userProtocolPO.setPhoneMd5(userRegisterPO.getPhoneMd5());
                    userProtocolPO.setUrl(H5DomainUrlUtils.createUserProtocolUrl(productApplyFlowPO.getLoanProductPlanId(), userRegisterPO.getPhoneMd5()));
                    userProtocolPO.setType(UserProtocolEnum.PRODUCT.getType());
                    userProtocolPO.setCreateTime(DateUtils.currentTime());
                    //  填充模板
                    RespPlatformPhoneMd5DataExchange apiPlatFormDataExchange = RespPlatformPhoneMd5DataExchange.parseByJson(productApplyFlowPO.getRespData());
                    String appendedTemplate = userProtocolService.appendTemplate(userRegisterPO, productTemplate, apiPlatFormDataExchange);
                    userProtocolPO.setText(appendedTemplate);
                    userProtocolService.insert(userProtocolPO);
                });
            }
        }

        //  关联进件数据并记录相关流程表
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.USER_ACCEPT.getType());
        insertProductApplyFlowPO.setBizStatus("1");
        apiUserRegister.uniqueBindProductUser(insertProductApplyFlowPO, userId);

        //  主体-单次计费
        RespPlatformPhoneMd5DataExchange apiPlatFormDataExchange = null;
        //  平台计划解析撞库成功时的单价
        if (hasPlatform) {
            apiPlatFormDataExchange = RespPlatformPhoneMd5DataExchange.parseByJson(productApplyFlowPO.getRespData());
        }
        BigDecimal originalPrice = hasPlatform ? apiPlatFormDataExchange.getPrice() : null;

        ProductAmountBO productAmountBO = new ProductAmountBO();
        productAmountBO.setProductId(productPlanPO.getLoanProductId());
        productAmountBO.setProductPlanId(productPlanPO.getId());
        productAmountBO.setUserId(userRegisterPO.getId());
        productAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
        productAmountBO.setLoanChannelId(insertProductApplyFlowPO.getLoanChannelId());
        productAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
        productAmountBO.setOriginalPrice(originalPrice);
        productAmountBO.setHasPlatform(hasPlatform);
        productAmountBO.setHasLocalExist(Boolean.FALSE);
        BigDecimal planPrice = productAmountService.deduct(productAmountBO);

        //  渠道扣款
        ApiKeyAmountBO apiKeyAmountBO = new ApiKeyAmountBO();
        apiKeyAmountBO.setProductId(productPlanPO.getLoanProductId());
        apiKeyAmountBO.setProductPlanId(productPlanPO.getId());
        apiKeyAmountBO.setUserId(userRegisterPO.getId());
        apiKeyAmountBO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        apiKeyAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
        apiKeyAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
        apiKeyAmountBO.setPlanPrice(planPrice);
        apiKeyAmountBO.setHasPlatform(hasPlatform);
        apiKeyAmountBO.setHasLocalExist(Boolean.FALSE);
        apiKeyAmountService.deduct(apiKeyAmountBO);

        //  发送短信-非平台才发送短信
        if (!hasPlatform) {
            smsService.sendCustomerNotice(userRegisterPO.getPhone(), productPlanPO.getDisplayName());
        }

        //  记录主动通知流程
        ProductApplyFlowPO pushNoticeProductApplyFlowPO = new ProductApplyFlowPO();
        pushNoticeProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        pushNoticeProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        pushNoticeProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        pushNoticeProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        pushNoticeProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        pushNoticeProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        pushNoticeProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.CHANNEL_PUSH_APPLY_NOTICE.getType());
        pushNoticeProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        pushNoticeProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        pushNoticeProductApplyFlowPO.setBizStatus("0");
        pushNoticeProductApplyFlowPO.setAreaName(userRegisterPO.getAreaName());
        pushNoticeProductApplyFlowPO.setAreaCode(userRegisterPO.getAreaCode());

        //  推送/拉取进件信息回调-请求对象
        ApiReceiveNotice applyNoticeMessage = new ApiReceiveNotice();
        applyNoticeMessage.setApiClientId(productApplyFlowPO.getApiClientId());
        applyNoticeMessage.setProductId(productPO.getId());
        applyNoticeMessage.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        applyNoticeMessage.setReqId(productApplyFlowPO.getReqId().toString());
        //  主动通知渠道接口-记录主动通知流程
        ApiHttpMessage apiPushNoticeHttpMessage = apiReceiveNoticeHttpHandler.sendPushApplyNotice(apiKeyPO, applyNoticeMessage);
        if (ValidParam.isNotNull(apiPushNoticeHttpMessage)) {
            pushNoticeProductApplyFlowPO.setCallUrl(productPO.getApiApplyUrl());
            pushNoticeProductApplyFlowPO.setReqData(String.valueOf(apiPushNoticeHttpMessage.getRequestBody()));
            pushNoticeProductApplyFlowPO.setRespData(apiPushNoticeHttpMessage.getResponseBody());
            pushNoticeProductApplyFlowPO.setRespCode(String.valueOf(apiPushNoticeHttpMessage.getRespCode()));
            //  主动通知是否成功
            boolean hasPushNoticeHttpRespSuc = apiBizRequiredService.hasNoticeHttpRespSuc(pushNoticeProductApplyFlowPO, apiPushNoticeHttpMessage, ProductApplyFlowStatusEnum.CHANNEL_PUSH_APPLY_NOTICE);
            if (hasPushNoticeHttpRespSuc) {
                pushNoticeProductApplyFlowPO.setBizStatus("1");
            }
            //  插入回调流程日志
            productApplyFlowService.insert(pushNoticeProductApplyFlowPO, true);
        }
    }
}
